package com.delayqueue.core.permanent;

import com.alibaba.fastjson.JSON;
import com.delayqueue.common.task.Task;
import com.delayqueue.core.common.FileUtil;
import com.delayqueue.core.permanent.executor.PermanentArchiveExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Iterator;

@Slf4j
@Component
public class PermanentWriter {

    private final Charset charset = StandardCharsets.UTF_8;
    private boolean cleaning = false;
    @Autowired
    private PermanentConfig permanentConfig;
    @Autowired
    private PermanentStream permanentStream;
    @Autowired
    private PermanentFile permanentFile;
    @Autowired
    private PermanentConsumer permanentConsumer;

    public void writeTask(File file) {
        HashSet<Task> dataList = FileUtil.loadTaskListFromFile(file);
        if (!dataList.isEmpty()) {
            Iterator<Task> iterator = dataList.iterator();
            while (iterator.hasNext()) {
                writeTask(iterator.next());
            }
        }
    }

    public void writeTask(Task task) {
        if (task != null) {
            writeTask(JSON.toJSONString(task));
        }
    }

    protected void init() {
        permanentStream.openDatStream();
    }

    private void writeTask(String json) {
        json += "\r\n";
        byte[] bytes = json.getBytes(charset);
        try {
            permanentStream.getTaskWriter().write(bytes);
            if (cleaning) {
                permanentStream.getTaskTempWriter().write(bytes);
            }
        } catch (IOException e) {
            log.error("写入task出错：", e);
        }
    }

    public void writeCompleted(File file) {
        HashSet<Task> dataList = FileUtil.loadTaskListFromFile(file);
        if (!dataList.isEmpty()) {
            Iterator<Task> iterator = dataList.iterator();
            while (iterator.hasNext()) {
                writeCompleted(iterator.next());
            }
        }
    }

    public void writeCompleted(Task task) {
        if (task != null) {
            String code = task.getCode();
            byte[] bytes = (code + "\r\n").getBytes(charset);
            try {
                permanentStream.getCompletedWriter().write(bytes);
            } catch (IOException e) {
                log.error("写入completed出错：", e);
            }
            if (cleaning) {
                try {
                    permanentStream.getCompletedTempWriter().write(bytes);
                } catch (IOException e) {
                    log.error("写入completedTemp出错：", e);
                }
            } else if (permanentConfig.getArchive()) {
                permanentConsumer.add(task, PermanentArchiveExecutor.class);
            }
        }
    }

    private void writeCompleted(String json) {
        json += "\r\n";
        byte[] bytes = json.getBytes(charset);
        try {
            permanentStream.getCompletedWriter().write(bytes);
            if (cleaning) {
                permanentStream.getCompletedTempWriter().write(bytes);
            }
        } catch (IOException e) {
            log.error("写入completed出错：", e);
        }
    }

    protected void changeStatusToCleaning() {
        permanentStream.openTempStream();
        this.cleaning = true;
    }

    protected void cancelStatusCleaning() {
        permanentFile.clearDataFile();
        this.cleaning = false;
        permanentStream.releaseTempStream();
        writeTask(permanentFile.getTaskTempFile());
        writeCompleted(permanentFile.getCompletedTempFile());
        permanentFile.deleteTempFile();
    }

}
